/**
 * @author: hdh
 * @date: 2022-06-18 13:54
 */
package com.yy.QSManage.tool;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONUtil;
import com.yy.QSManage.exception.ServiceException;
import com.yy.QSManage.model.entity.FaSysMember;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * {阐述类的作用}
 * @author: HuDeHong
 * @date: 2022-06-18 13:54
 */
@Component
@Slf4j
public class RequestBuffUtil {

    private final String MEMBER_TOKEN = "member_token:{}";

    @Autowired
    RedisTool redisTool;

    public static HttpServletRequest getRequest() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if(Objects.isNull(attributes)){
            return null;
        }
        HttpServletRequest request = attributes.getRequest();
        if(Objects.isNull(request)){
            return null;
        }
        return request;
    }

    public static HttpServletResponse getResponse() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if(Objects.isNull(attributes)){
            return null;
        }
        HttpServletResponse response = attributes.getResponse();
        if(Objects.isNull(response)){
            return null;
        }
        return response;
    }

    /**
     * 获取ip地址
     * @param
     * @return: java.lang.String
     * @author: HuDeHong
     * @date: 2023-04-27 10:55
     */
    public static String getIp() {
        HttpServletRequest request = getRequest();
        String ip = null;    //X-Forwarded-For：Squid 服务代理
        String ipAddresses = request.getHeader("X-Forwarded-For");
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {        //Proxy-Client-IP：apache 服务代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {        //WL-Proxy-Client-IP：weblogic 服务代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {        //HTTP_CLIENT_IP：有些代理服务器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {        //X-Real-IP：nginx服务代理
            ipAddresses = request.getHeader("X-Real-IP");
        }    //有些网络通过多层代理，那么获取到的ip就会有多个，一般都是通过逗号（,）分割开来，并且第一个ip为客户端的真实IP
        if (ipAddresses != null && ipAddresses.length() != 0) {
            ip = ipAddresses.split(",")[0];
        }    //还是不能获取到，最后再通过request.getRemoteAddr();获取
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    public static String getGridId(){
        HttpServletRequest request = getRequest();
        String gridId = null;
        if (request != null) {
            gridId = request.getHeader("gridId");
        }
        if(Objects.isNull(gridId)){
            throw new ServiceException("缺少网格id");
        }
        return gridId;
    }

    public static String getToken(){
        HttpServletRequest request = getRequest();
        if(Objects.isNull(request)){
            throw new ServiceException("未登录");
        }
        String token = request.getHeader("token");
        if(StrUtil.isEmpty(token)){
            throw new ServiceException("未登录");
        }
        return token;
    }

    /**
     * 获取body
     * 在全局过滤器中，对所有请求通过重载HttpServletRequestWrapper的getInputStream复写HttpServletRequest请求，将body参数读取出来后，
     * 存入请求的attribute属性中，后面如果有需要再次获取参数时，不再通过流读取，而是直接通过setAttribute方法获取。
     * 此外，body参数在HttpServletRequestWrapper中读取后，记得重置流读取标志位，不要影响后面接口的正常使用
     * @param
     * @return: java.lang.Object
     * @author: HuDeHong
     * @date: 2023-04-28 10:14
     */
    public static Object getBody(){
        HttpServletRequest request = getRequest();
        return request.getAttribute("body");
    }

    public FaSysMember getTokenMember(String token) {
        String memberToken = StrUtil.format(MEMBER_TOKEN, DigestUtil.md5Hex(token));
        // 获取公钥
        String publicKey = redisTool.get(memberToken).toString();
        Object memberObj = JwtTool.getPayload(token, publicKey, "member");
        return JSONUtil.toBean(JSONUtil.parseObj(memberObj), FaSysMember.class);
    }

    public FaSysMember getTokenMember() {
        return getTokenMember(RequestBuffUtil.getToken());
    }

    public String getTokenMemberId() {
        FaSysMember tokenMember = getTokenMember();
        if(Objects.isNull(tokenMember)){
            return null;
        }
        return tokenMember.getId();
    }
}
